package com.lc.communication.handle;

import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.lc.communication.constants.ChannelConstant;
import com.lc.communication.service.HeartBeatClient;
import com.lc.communication.util.ChannelMap;
import com.lc.communication.util.LcHttpUtils;
import com.lc.communication.vo.MessageProtocol;
import com.lc.communication.vo.RequestVo;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.EventLoop;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.TimeUnit;

/**
 * @author liuhf17
 * @version 1.0.0
 * @ClassName HeartBeatClientHandler.java
 * @Description TODO
 * @createTime 2024年06月11日 14:16:00
 */
public class HeartBeatClientHandler extends SimpleChannelInboundHandler<MessageProtocol> {
    private static final Logger log = LoggerFactory.getLogger(HeartBeatClientHandler.class);

    //客户端名称
    private String clientName;

    //客户端uuid
    private String uuid;

    //服务端ip
    private String ip;

    //服务端端口
    private int port;


    public HeartBeatClientHandler(String clientName, String uuid, String ip, int port) {
        super();
        this.ip = ip;
        this.port = port;
        this.clientName = clientName;
        this.uuid = uuid;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MessageProtocol mp) throws Exception {
        log.info(" ====== > [client] message received : {}", JSONUtil.toJsonStr(new String(mp.getContent())));
        RequestVo msg = null;
        try {
            msg = JSONUtil.toBean(new String(mp.getContent()), RequestVo.class);
        } catch (Exception e) {
            log.error("error 结构错误：{}", mp);
            RequestVo requestVo = new RequestVo();
            requestVo.setError("client recognition msg is null");
            log.error(JSONUtil.toJsonStr(requestVo));
            return;
        }
        //关闭请求处理
        if (ChannelConstant.IDLE_CLOSE.equals(msg.getType())) {
            log.warn("服务端关闭连接，客户端也关闭");
            //ChannelMap.CHANNEL_MAP.remove(ChannelMap.CLIENT_A);
            ctx.channel().closeFuture();
        } else if (ChannelConstant.TYPE_HEART.equals(msg.getType())) {
            log.info("客户端收到服务端心跳回复 msg：[{}]", JSONUtil.toJsonStr(msg));
            refreshChannelMap(msg, ctx.channel());
        }
        //服务端告知客户端连接建立，记录channel
        else if (ChannelConstant.CLIENT_LINK_SUCCESS.equals(msg.getType())) {
            //String key = ChannelConstant.SERVER_UUID + vo.getClientUuid();
            log.info("CHANNEL_SERVER_MAP_KEY：{}", msg.getClientUuid());
            //服务端记录发给客户端的 channel；接收方是客户端
            ChannelMap.CHANNEL_SERVER_MAP.put(msg.getClientUuid(), ctx.channel());
            if (!ChannelMap.CLIENT_NAME_UUID.containsKey(msg.getClientName())) {
                ChannelMap.CLIENT_NAME_UUID.put(msg.getClientName(), msg.getClientUuid());
            }
        }
        //处理http请求
        else if (ChannelConstant.REQUEST_MSG.equals(msg.getType())) {
            //获取本次消息唯一标识
            //if (ChannelMap.resultMap.containsKey(msg.getId())) {
            //log.info("client 收到服务端消息，即将发起http请求本次消息id：{}", msg.getId());
            HttpResponse response = LcHttpUtils.toRequest(msg);
            msg.setHandleFlag(true);
            if (null == response) {
                msg.setResBody("开发中敬请期待。。。");
            } else if (response.isOk()) {
                msg.setResBody(response.body());
            } else {
                msg.setError(response.body());
            }
            //ChannelMap.resultMap.put(msg.getId(), JSONUtil.toJsonStr(msg));
            msg.setRemark("client 回复 ChannelConstant.REQUEST_MSG");
            log.info("client 收到服务端消息，http请求本次消息id：{}, vo:{}", msg.getId(), JSONUtil.toJsonStr(msg));
            //如果回复客户端那么是异步处理
            ctx.channel().writeAndFlush(msg.toRequestVo());
            //
            //}

        } else {
            msg.setResBody("client回复：收到 todo 待开发。。。");
            log.warn(JSONUtil.toJsonStr(msg));
            //ctx.channel().writeAndFlush(msg);
        }
    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.warn("channelInactive 掉线了...");
        ChannelMap.CHANNEL_SERVER_MAP.remove(uuid);
        //使用过程中断线重连
        final EventLoop eventLoop = ctx.channel().eventLoop();
        eventLoop.schedule(() -> {
            //ChannelMap.CHANNEL_MAP.remove(ChannelMap.CLIENT_A);
            HeartBeatClient.Connection.connect(clientName, uuid, ip, port);
        }, 1L, TimeUnit.SECONDS);
        super.channelInactive(ctx);
    }

    public void refreshChannelMap(RequestVo vo, Channel channel) {
        ChannelMap.CHANNEL_SERVER_MAP.put(vo.getClientUuid(), channel);
    }
}
